import { useState, useRef, useEffect, useCallback, useMemo } from "react";
import { SafeAreaView, StatusBar, Text, View, StyleSheet, useWindowDimensions } from "react-native";
import { useSelector, useDispatch } from "react-redux";

import VideoPlayer from "react-native-video";
import VideoPlayerControns from "react-native-media-console";
// https://github.com/wonday/react-native-pdf
import Pdf from "react-native-pdf";
// https://github.com/react-native-webview/react-native-webview
import Webview from "react-native-webview";

import type { LoadError, OnLoadData, VideoProperties } from "react-native-video";
import type { WebViewMessageEvent } from "react-native-webview";
import type { RootState } from "@/store";
import type { VideoDisplayProps } from "@/router/routerType";
import type { StateType } from "./type";

import { materialSqlh, scheduleSqlh } from "@/sqlite/exports";

import fso from "@/utils/FileOperate/operate";
import sm from "@/utils/ScheduleManage/operate";
import { getEntryNetworkInfo } from "@/utils/entryNetworkInfoOperate";
import { connect as websocketConnect } from "@/utils/websocket/index";

import Btn from "@/components/Btn";
import CoverContent from "@/components/CoverContent";

import ErrTip from "@/pages/VideoDisplay/ErrTip";
import PolyfillImg from "@/pages/VideoDisplay/PolyfillImg";
import FullScreenImg from "@/pages/VideoDisplay/FullScreenImg";

import config from "@/config";
import globalMethods from "@/GlobalMethodProvider";

import store from "@/store";
import styles from "./styles";
import DevComp from "./DevComp";
import getDeviceInfo from "@/utils/getDeviceInfo";

// 播放器
const VideoDisplay = (props: VideoDisplayProps) => {
  const pdfRef = useRef<Pdf>(null);
  // const webViewRef = useRef<Webview>(null);
  const isInit = useRef(false);

  const [state, _setState] = useState<StateType>({
    repeat: true,
    paused: false,
    rate: 1,
    hiddenStatusBar: true,
    deviceInfo: null
  });

  // 通用更新状态单个
  const setState = useCallback((field: keyof typeof state, val: any) => {
    _setState(_state => {
      return { ..._state, [field]: val };
    });
  }, []);

  // 通用更新状态(对象)
  const setObjState = useCallback((obj: Partial<typeof state>) => {
    _setState(_state => {
      return { ..._state, ...obj };
    });
  }, []);

  const dispatch = useDispatch();
  const { width: windowWidth, height: windowHeight } = useWindowDimensions();

  const { common: reduxCommon, index: reduxIndex } = useSelector((state: RootState) => state);

  const curPlayData = useMemo(() => {
    return reduxIndex.curPlayData;
  }, [reduxIndex.curPlayData]);

  const isCustomWH = useMemo(() => {
    return curPlayData.width !== 0 && curPlayData.height !== 0 ? true : false;
  }, [curPlayData]);

  /** 获取初始化参数 */
  const getInitData = useCallback(async () => {
    try {
      if (reduxCommon.networkState) {
        // 向后台同步排期
        const flag = await sm.syncSchedule();
        if (!flag) fso.error("排期数据同步失败");
      } else {
        fso.info("当前没有网络连接, 不同步排期数据");
        sm.loopSeek();
      }
    } catch (err) {
      console.log("err: ", err);
      fso.error("发生了错误: ", err);
    }
  }, [reduxCommon.networkState]);

  useEffect(() => {
    if (isInit.current) {
      console.warn("重复初始化");
      return;
    }
    isInit.current = true;

    getDeviceInfo().then(res => {
      if (res) setObjState({ deviceInfo: res });
    });

    getInitData();
    websocketConnect();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  /** 加载媒体并准备播放时调用的回调函数 */
  const onLoad = (e: OnLoadData) => {
    sm.videoOnload(e);
    // console.log(`${reduxIndex.curPlayData.filePath} 视频加载完成: `, e);
  };

  /** 播放错误时回调 */
  const onError = (err: LoadError) => {
    console.log("onError: ", err);
    fso.error("视频解析失败错误原因: ", err);
    fso.error("视频解析失败素材数据: ", curPlayData);

    // 切换为垫片
    sm.playPolyfill();

    // 停止排期查找
    sm.stopSeek();

    // 当前正在下载素材则不操作, 因为下载完成后会再开启排期查找
    if (sm.downloadingTaskData.length) return;

    // TODO 重新检查素材, 如果没有问题则表示播放器有问题, 有问题则删除异常的素材
    // console.log("curPlayData: ", curPlayData);

    // 重头开始继续播放, 因为前面把当前播放的素材变成了垫片
    sm.loopSeek();
  };

  /**
   * 获取播放器组件
   * @param width 宽度
   * @param height 高度
   * @returns
   */
  const getVideoComp = (width: number, height: number) => {
    // width = 500;
    // height = 300;

    const isCustomWH = width !== 0 && height !== 0 ? true : false;

    const playProp: VideoProperties = {
      ...state,
      // 直接读取本地资源, 不需要加 file:// 前缀
      source: { uri: curPlayData.filePath },
      resizeMode: "contain",
      // resizeMode: isCustomWH ? 'contain' : 'cover',
      onLoad,
      onError
    };

    // 体育西路的视源设备, 是 tvos, react-native-media-console 内部不兼容, 使用 react-native-video
    if (state.deviceInfo?.brand === "Droidlogic") {
      return <VideoPlayer {...playProp} style={isCustomWH ? { width, height } : StyleSheet.absoluteFill} />;
    } else {
      return (
        <VideoPlayerControns
          {...playProp}
          isFullscreen // 默认全屏
          showDuration // 显示视频时长
          disableBack // 禁用返回按钮
          disableFullscreen // 禁用全屏按钮
          disableVolume // 禁用音量调节
          showOnStart={false} // 开始时隐藏控件
          showOnEnd={false} // 结束时时隐藏控件
          containerStyle={isCustomWH ? { width, height } : StyleSheet.absoluteFill} // 容器样式
        />
      );
    }

    // return (
    //   <Webview
    //     style={{
    //       width: windowWidth,
    //       height: windowHeight,
    //       backgroundColor: "black"
    //     }}
    //     // ref={webViewRef}
    //     scalesPageToFit={false}
    //     sharedCookiesEnabled={true}
    //     allowUniversalAccessFromFileURLs={true}
    //     allowFileAccessFromFileURLs={true}
    //     allowFileAccess={true}
    //     startInLoadingState={true}
    //     pullToRefreshEnabled={true}
    //     allowsBackForwardNavigationGestures={true}
    //     // onContentProcessDidTerminate={() => webViewRef.current?.reload()}
    //     mediaPlaybackRequiresUserAction={false}
    //     allowsInlineMediaPlayback={true}
    //     allowsFullscreenVideo={false}
    //     onMessage={(event: WebViewMessageEvent) => {
    //       console.log("onMessage: ", event.nativeEvent.data);
    //     }}
    //     onLoad={res => {
    //       console.log("onload: ", res);
    //     }}
    //     // https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video#%E4%BA%8B%E4%BB%B6
    //     source={{
    //       html: `
    //       <script>
    //         window.onload = () => {
    //           // document.body.style.backgroundColor = "red";
    //           // 绑定td点击事件
    //           const video = document.querySelector(".video");
    //           window.ReactNativeWebView.postMessage(video);
    //           video.onloadedmetadata = function (e) {
    //             // const dataSourceId = this.getAttribute("data-sourceId");
    //             // window.ReactNativeWebView.postMessage(dataSourceId);
    //             window.ReactNativeWebView.postMessage(e);
    //           }
    //         }
    //       </script>

    //       <video class="video" style="object-fit: fill;" width="${windowWidth}" height="${windowHeight}" playsInline controls autoplay loop src="file:///${curPlayData.filePath}"  type="video/mp4"></video>
    //       `
    //     }}
    //   />
    // );
  };

  /** 获取播放器组件 */
  const getImgComp = (width: number, height: number) => {
    const isCustomWH = width !== 0 && height !== 0 ? true : false;
    let result;
    const uri = "file:///" + reduxIndex.curPlayData.filePath;
    if (isCustomWH) {
      result = <FullScreenImg uri={uri} resizeMode="contain" style={{ width, height }} />;
    } else {
      result = <FullScreenImg uri={uri} resizeMode="contain" />;
    }
    return result;
  };

  /** 获取PDF组件 */
  const getPDFComp = (width: number, height: number) => {
    const isCustomWH = width !== 0 && height !== 0 ? true : false;
    const uri = "file:///" + reduxIndex.curPlayData.filePath;
    return (
      <Pdf
        // 2435
        style={[isCustomWH ? { width, height } : StyleSheet.absoluteFill, { backgroundColor: "#000" }]}
        source={{ uri }}
        // fitPolicy={0} // 宽度自适应
        ref={pdfRef}
        onLoadComplete={(numberOfPages, filePath) => {
          sm.pdfOnLoadComplete(numberOfPages, filePath, count => {
            if (pdfRef.current) pdfRef.current.setPage(count);
          });

          // console.log(`onLoadComplete: ${numberOfPages} ${filePath}`);
        }}
        onPageChanged={(page, numberOfPages) => {
          // console.log(`onPageChanged: ${page} ${numberOfPages}`);
        }}
        onError={error => {
          // console.log("发生了错误: " + error);
          sm.playPolyfill();
          sm.loopSeek();
          fso.error("PDF加载发生了错误: ", error);
        }}
        onPressLink={uri => {
          // console.log(`Link pressed: ${uri}`);
        }}
      />
    );
  };

  // 有错误则显示错误组件
  let ContentComp;

  // 垫片
  if (curPlayData.type === "POLYFILL") {
    ContentComp = <PolyfillImg />;

    // 错误
  } else if (curPlayData.type === "ERROR") {
    ContentComp = <ErrTip errTip={curPlayData.content} />;

    // 视频
  } else if (curPlayData.type === "4") {
    ContentComp = getVideoComp(curPlayData.width, curPlayData.height);

    // PDF
  } else if (curPlayData.type === "2") {
    ContentComp = getPDFComp(curPlayData.width, curPlayData.height);

    // 图片
  } else if (curPlayData.type === "1") {
    ContentComp = getImgComp(curPlayData.width, curPlayData.height);
  } else {
    // ContentComp = <ErrTip errTip={`不支持的素材类型【${curPlayData.type}】, 请联系管理员处理`} />;
    ContentComp = <PolyfillImg />;
    fso.warn(`不支持的素材类型【${curPlayData.type}】, 播放垫片`, curPlayData);
  }

  return (
    <SafeAreaView style={styles.container}>
      <StatusBar hidden={state.hiddenStatusBar} />
      {ContentComp}

      {config.IS_DEBUG && (
        <CoverContent position="top-right">
          <Text style={{ color: "red", fontSize: 14, fontWeight: "bold" }}>开发中内容, 仅供参考</Text>
        </CoverContent>
      )}

      {config.IS_DEBUG && reduxIndex.nextMaterial && (
        <CoverContent position="bottom-right">
          <Text style={{ color: "#a8abb9", fontSize: 12 }}>下一播放素材: {reduxIndex.nextMaterial.fileName}</Text>
        </CoverContent>
      )}

      {config.IS_DEBUG && (
        <View style={styles.btnContainer}>
          <Btn
            type="primary"
            text="查看数据"
            onClick={async () => {
              try {
                console.log("state: ", state);
                console.log("state redux: ", store.getState());

                const entryNetworkInfo = await getEntryNetworkInfo();
                console.log("entryNetworkInfo: ", entryNetworkInfo);

                const res1 = await scheduleSqlh?.getList();
                console.log("排期数据: ", res1);

                const res2 = await materialSqlh?.getList();
                console.log("素材数据: ", res2);
              } catch (err) {
                console.log("err: ", err);
              }
            }}
          />
          <Btn
            type="primary"
            text="播放错误回调"
            onClick={() => {
              onError({ text: "测试的错误" } as any);
            }}
          />

          <DevComp />
        </View>
      )}
    </SafeAreaView>
  );
};

export default VideoDisplay;
